package zisu.rabbitmqspringboot.rbsb.consumer;
import com.rabbitmq.client.Channel;
import org.springframework.amqp.rabbit.annotation.*;
import org.springframework.amqp.support.AmqpHeaders;
import org.springframework.messaging.handler.annotation.Headers;
import org.springframework.messaging.handler.annotation.Payload;
import org.springframework.stereotype.Component;
import java.util.Map;

/**
 * @Author: 蔡翔
 * @Date: 2019/8/19 14:58
 * @Version 1.0
 * （重要）
 */
//把这个类注入到spring容器里面。当main类启动后，这些类都会自动执行，当然那些需要调用的类不会执行。
@Component
public class RabbitReceiver {


    //一个队列代表一个AGV，一个exchange 绑定多个队列。
    //模拟第一台AGV
    /**
     * spring.rabbitmq.listener.order.queue.name=queue-2
     * spring.rabbitmq.listener.order.queue.durable=true
     * spring.rabbitmq.listener.order.exchange.name=exchange-2
     * spring.rabbitmq.listener.order.exchange.durable=true
     * spring.rabbitmq.listener.order.exchange.type=topic
     * spring.rabbitmq.listener.order.exchange.ignoreDeclarationExceptions=true
     * spring.rabbitmq.listener.order.key=springboot.*
     * */
    //@RabbitListener和@RabbitHandler 是配套使用的。
    //@RabbitListener 标注在类上面表示当有收到消息的时候，就交给 @RabbitHandler 的方法处理，具体使用哪个方法处理
    //*** 使用注解的方式，就算没有exchange-1 和 queue-1 注解也会帮你自动创建出来。
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${spring.rabbitmq.listener.order.queue.name}"
                    ,durable = "${spring.rabbitmq.listener.order.queue.durable}"),
            exchange = @Exchange(value = "${spring.rabbitmq.listener.order.exchange.name}"
                    ,durable = "${spring.rabbitmq.listener.order.exchange.durable}"
                    , type = "${spring.rabbitmq.listener.order.exchange.type}"
                    ,ignoreDeclarationExceptions = "${spring.rabbitmq.listener.order.exchange.ignoreDeclarationExceptions}"),//最后一个支持过滤
            key = "AGV1.*"
        )
    )
    //1.
    /*@RabbitHandler
    public void onMessage(Message message, Channel channel) throws Exception{
        System.err.println("------------------------------------------");
        //message.getPayload() 就是消息体  hello rabbitmq for springBoot
        System.err.println("消费单收到消息体内容："+message.getPayload());
        Long deliveryTag = (Long)message.getHeaders().get(AmqpHeaders.DELIVERY_TAG);
        //手工ACK
        channel.basicAck(deliveryTag,false);
    }*/

    //2.
    //这里参数就不需要Message了，@Payload 就是需要加载Order 这个类。作为形式参数。
    //参数本来是Message 这里把它给拆开了拆成了两部分@Payload 和 @Headers。而 @Payload就是 Order 这个实体（消息类里面的）。而@Headers 也是Map型的
    @RabbitHandler
    public void onMessage(@Payload zisu.rabbitmqspringboot.rbsb.entity.Order order, Channel channel, @Headers Map<String,Object> headers) throws Exception{
        //message.getPayload() 就是消息体  hello rabbitmq for springBoot
        System.err.println("AGV11==Order："+order.getId()+" message:"+order.getName());
        Long deliveryTag = (Long)headers.get(AmqpHeaders.DELIVERY_TAG);
        //手工ACK
        channel.basicAck(deliveryTag,false);
    }

    //模拟第二台AGV
    @RabbitListener(bindings = @QueueBinding(
            value = @Queue(value = "${spring.rabbitmq.listener.order.queue2.name}"
                    ,durable = "${spring.rabbitmq.listener.order.queue.durable}"),
            exchange = @Exchange(value = "${spring.rabbitmq.listener.order.exchange.name}"
                    ,durable = "${spring.rabbitmq.listener.order.exchange.durable}"
                    , type = "${spring.rabbitmq.listener.order.exchange.type}"
                    ,ignoreDeclarationExceptions = "${spring.rabbitmq.listener.order.exchange.ignoreDeclarationExceptions}"),//最后一个支持过滤
            key = "AGV1.*"
    )
    )
    @RabbitHandler
    public void onMessages(@Payload zisu.rabbitmqspringboot.rbsb.entity.Order order, Channel channel, @Headers Map<String,Object> headers) throws Exception{
        //message.getPayload() 就是消息体  hello rabbitmq for springBoot
        System.err.println("AGV12==Order："+order.getId()+" message:"+order.getName());
        Long deliveryTag = (Long)headers.get(AmqpHeaders.DELIVERY_TAG);
        //手工ACK
        channel.basicAck(deliveryTag,false);
    }
}
